package com.gm.wj.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.gm.wj.FrontEndTemplate.MessageTemplate;
import com.gm.wj.config.AlipayConfig;
import com.gm.wj.entity.PtCaptain;
import com.gm.wj.entity.PtMember;
import com.gm.wj.entity.SysFlow;
import com.gm.wj.entity.SysOrder;
import com.gm.wj.result.Result;
import com.gm.wj.result.ResultFactory;
import com.gm.wj.service.AliPayService;
import com.gm.wj.service.PtService;
import com.gm.wj.service.SysOrderFlowService;
import com.gm.wj.util.MyTime;
import com.gm.wj.util.StringUtils;
import com.gm.wj.util.SysLoging;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


@Log4j2
@RestController
@Api(tags = "支付相关接口")
public class PayController {

    @Autowired
    SysOrderFlowService sysOrderFlowService;
    @Autowired
    PtService ptService;
    @Autowired
    AliPayService aliPayService;

    //订单发起方法
    @GetMapping("api/alipay")
    public String alipay(int id) {

        SysOrder sysOrder = sysOrderFlowService.findById(id);

        boolean flag = MyTime.longBySize(MyTime.getStringDate(),sysOrder.getEndTime());
        log.info("订单是否过期-->{}-->{}", sysOrder.getOrderStatus(), flag);
        // 订单过期
        if (sysOrder.getOrderStatus() == 2 || flag) {
            log.warn("订单已过期  {}", flag);
            return MessageTemplate.MessageAli( "订单已过期");
        }

        // 商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = sysOrder.getOrderId();//采用时间戳当做订单号
        // 订单名称，必填
        String subject = sysOrder.getProductName();
        // 将要付款的金额，必填
        String total_amount= sysOrder.getOrderAmount();
        // 销售产品码 必填
        String product_code="QUICK_WAP_WAY";
        // 商品描述，可空
        String body = "";
        // 超时时间 可空  5min
        String timeout_express="5m";
        /**********************/
        // SDK 公共请求类，包含公共请求参数，以及封装了签名与验签，开发者无需关注签名与验签
        // 调用RSA签名方式
        AlipayClient client = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.APPID, AlipayConfig.RSA_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE);

        /**
        // 创建手机网站支付API对应的request类(主要是这里变化了)
         AlipayTradeWapPayRequest alipay_request =new AlipayTradeWapPayRequest();
        // 封装请求手机支付信息
        AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
        model.setOutTradeNo(out_trade_no);
        model.setSubject(subject);
        model.setTotalAmount(total_amount);
        model.setBody(body);
        model.setTimeoutExpress(timeout_express);
        model.setProductCode(product_code);
        alipay_request.setBizModel(model);
         **/

        // 创建电脑网站支付对应api的request类
        AlipayTradePagePayRequest alipay_request = new AlipayTradePagePayRequest();
        //封装参数
        AlipayTradePagePayModel model = new AlipayTradePagePayModel();
//        model.setOutTradeNo(UUID.randomUUID().toString());//商品id
        model.setOutTradeNo(out_trade_no);
        model.setBody(body);//商品描述
        model.setSubject(subject);//商品名称
        model.setTimeoutExpress(timeout_express);//超时
        model.setTotalAmount(total_amount);//支付金额
        model.setProductCode("FAST_INSTANT_TRADE_PAY");
        //设置request参数
        alipay_request.setBizModel(model);
        /*alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");*/


        // 设置异步通知地址
        alipay_request.setNotifyUrl(AlipayConfig.notify_url);
        // 设置同步地址
        alipay_request.setReturnUrl(AlipayConfig.return_url);

        // form表单生产
        String form = "";
        try {
            // 调用SDK生成表单
            form = client.pageExecute(alipay_request).getBody();
//            return ResultFactory.buildSuccessResult(form);
            return form;
        } catch (AlipayApiException  e) {
            e.printStackTrace(); // 在控制台打印出异常种类，错误信息和出错位置等
//            return ResultFactory.buildFailResult("服务器出错了，请联系管理员。错误信息：" + e.getMessage());
            return "失败";
        }
    }

    /////////////////////////////一般同步接口仅检查参数是否正确，签名是否无误等。异步接口才告诉你扣款结果。

    //同步回调处理方法
    @GetMapping("/return_url")
    public String return_url(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {
        //获取支付宝GET过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        //商户订单号

        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

        //支付宝交易号

        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

        // 买方实付金额
        String buyer_pay_amount = new String(request.getParameter("buyer_pay_amount").getBytes("ISO-8859-1"),"UTF-8");

        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        //计算得出通知验证结果
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");

        if(verify_result){//验证成功
            //////////////////////////////////////////////////////////////////////////////////////////
            //请在这里加上商户的业务逻辑程序代码
            //该页面可做页面美工编辑
            log.warn("👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇");
            log.warn("👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇");
            log.warn("-------------------  支付宝   -------------------");
            log.warn("-------------------  AliPay  -------------------");
            log.warn("------------------- 同步回调处理-验证成功 -------------------");
            log.warn("-------------------  AliPay  -------------------");
            log.warn("👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆");
            log.warn("👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆");
            //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

            //处理标记付款成功    ！！！一般同步接口仅检查参数是否正确，签名是否无误等。异步接口才告诉你扣款结果。
//            saveFlow(out_trade_no, trade_no,buyer_pay_amount);

            return "http://localhost:8080/admin/order/order";//跳转到订单信息页面

            //////////////////////////////////////////////////////////////////////////////////////////
        }else{
            //该页面可做页面美工编辑
            System.out.println("同步回调处理-验证失败");
            return "同步回调处理-验证失败";//跳转到首页
        }
    }


    //异步回调处理方法
    @ResponseBody
    @PostMapping("/notify_url")
    public String notify_url(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
//                System.out.println("POST过来反馈信息1=="+valueStr);
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)

        //商户订单号
        String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

        //支付宝交易号
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

        //交易状态
        String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

        // 买方实付金额
        String buyer_pay_amount = new String(request.getParameter("buyer_pay_amount").getBytes("ISO-8859-1"),"UTF-8");

        //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        //计算得出通知验证结果
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2");

        if(verify_result){//验证成功
            //////////////////////////////////////////////////////////////////////////////////////////
            //请在这里加上商户的业务逻辑程序代码

            //处理标记付款成功
            aliPayService.saveFlow(out_trade_no, trade_no,buyer_pay_amount,0); // 支付方式：0-线上支付，1-现金支付

            //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
            if(trade_status.equals("TRADE_FINISHED")){
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理，不执行商户的业务程序

                //注意：
                //如果签约的是可退款协议，退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
                //如果没有签约可退款协议，那么付款完成后，支付宝系统发送该交易状态通知。
            } else if (trade_status.equals("TRADE_SUCCESS")){
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理，不执行商户的业务程序

                //注意：
                //如果签约的是可退款协议，那么付款完成后，支付宝系统发送该交易状态通知。
            }

            //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
            log.warn("👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇");
            log.warn("👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇");
            log.warn("-------------------  支付宝   -------------------");
            log.warn("-------------------  AliPay  -------------------");
            log.warn("---------------- 异步回调处理-验证成功 -------------");
            log.warn("-----------------  AliPay成功  ------------------");
            log.warn("👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆");
            log.warn("👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆👆");
            return "success";	//请不要修改或删除

        }else{//验证失败
            System.out.println("异步回调处理-验证失败");
            return "异步回调处理-验证失败";
        }
    }

    // 现金支付
    @PostMapping("api/admin/xianjinpay/{id}")
    @SysLoging("现金支付")
    @ApiOperation("现金支付信息的接口")
    public Result xianjinpay(@PathVariable("id") int id) {
        try{
            //支付宝交易号//商户订单号/交易金额
            SysOrder sysOrder = sysOrderFlowService.findById(id);
            log.info(sysOrder.toString());
            int flag = aliPayService.saveFlow(sysOrder.getOrderId(),StringUtils.generateOrderNo(),sysOrder.getOrderAmount(),1);  // 支付方式：0-线上支付，1-现金支付
            if (flag == 1){
                return ResultFactory.buildSuccessResult("支付成功！",null);
            } else if (flag == 2) {
                return ResultFactory.buildFailResult("已经存在订单流水了");
            } else {
                return ResultFactory.buildFailResult("支付操作失败！");
            }
        } catch (Exception e){
            e.printStackTrace(); // 在控制台打印出异常种类，错误信息和出错位置等
            return ResultFactory.buildFailResult("服务器出错了，请联系管理员。错误信息：" + e.getMessage());
        }
    }

}
